# 读取元数据，在数据库中存储节点
# 节点包括：软件包节点

from py2neo import Node, Subgraph
from graph_util import *


def build_package_node(pkg_ori):
    """ 根据包原始信息构建图的包节点并返回为 json 对象
    :param pkg_ori: 包基础信息
    :return: 图的包节点信息 json 对象
    """
    pkg_node = {
        'id': pkg_ori['name'] + pkg_ori['version'],
        'name': pkg_ori['name'],
        'version': pkg_ori['version'],
        'expired': pkg_ori['expired'] if 'expired' in pkg_ori else 'false',
        'info': get_value(pkg_ori, 'info'),
        'publish_time': get_value(pkg_ori, 'publish_time'),
        'in': len(pkg_ori['dependencies']),
        'out': len(pkg_ori['dependents']),
        'change_log_url': pkg_ori['changeLogs'][0]['url'] if 'changeLogs' in pkg_ori and len(
            pkg_ori['changeLogs']) > 0 else '',
        'download_url': pkg_ori['download']['addr'] if 'download' in pkg_ori and pkg_ori[
            'download'] is not None else '',
        'download_sha256': pkg_ori['download']['checksum'] if 'download' in pkg_ori and pkg_ori[
            'download'] is not None else '',
        'license': get_value(pkg_ori, 'license'),
        'repository': get_value(pkg_ori, 'repository'),
        'publish_as': get_value(pkg_ori, 'publish_as')}
    return pkg_node


def loop_store_node():
    pkgs_json = load_pkgs()
    graph = get_graph()
    graph.delete_all()
    count = 1
    for name, val1 in pkgs_json.items():
        for version, pkg in val1.items():
            graph.create(Node('Package', **build_package_node(pkgs_json[name][version])))
            print(f'第{count}个节点完成 ', end='\n' if count % 10 == 0 else '')
            count = count + 1


def batch_store_node():
    """ 批量存储节点，大幅提升速度
    """
    pkgs_json = load_pkgs()
    graph = get_graph()
    nodes = []
    for name, val1 in pkgs_json.items():
        for version, pkg in val1.items():
            nodes.append(Node('Package', **build_package_node(pkgs_json[name][version])))
    # 事务提交保证原子性
    tx = graph.begin()
    # graph.delete_all()  # 删除原来的数据
    graph.create(Subgraph(nodes=nodes))
    graph.commit(tx)


if __name__ == '__main__':
    batch_store_node()
